

//给定两个整数数组 inorder 和 postorder ，其中 inorder 是二叉树的中序遍历， postorder 是同一棵树的后序遍历，请你构造并
//返回这颗 二叉树 。 
//
// 
//
// 示例 1: 
//
// 
//输入：inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
//输出：[3,9,20,null,null,15,7]
// 
//
// 示例 2: 
//
// 
//输入：inorder = [-1], postorder = [-1]
//输出：[-1]
// 
//
// 
//
// 提示: 
//
// 
// 1 <= inorder.length <= 3000 
// postorder.length == inorder.length 
// -3000 <= inorder[i], postorder[i] <= 3000 
// inorder 和 postorder 都由 不同 的值组成 
// postorder 中每一个值都在 inorder 中 
// inorder 保证是树的中序遍历 
// postorder 保证是树的后序遍历 
// 
// Related Topics 树 数组 哈希表 分治 二叉树 
// 👍 703 👎 0


import com.sun.glass.ui.Size;

/**
 * 106.从中序与后序遍历序列构造二叉树.construct-binary-tree-from-inorder-and-postorder-traversal
 *
 * @author orz
 * @since 2022-03-27 15:53:05
 **/

class Solution_106 {
    public static void main(String[] args) {
        Solution solution = new Solution_106().new Solution();
    }
    //leetcode submit region begin(Prohibit modification and deletion)

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     * int val;
     * TreeNode left;
     * TreeNode right;
     * TreeNode() {}
     * TreeNode(int val) { this.val = val; }
     * TreeNode(int val, TreeNode left, TreeNode right) {
     * this.val = val;
     * this.left = left;
     * this.right = right;
     * }
     * }
     */
    class Solution {
        public TreeNode buildTree(int[] inorder, int[] postorder) {
            //与前中序遍历的区别就是后序的数据刚好是反着来的
            return build(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
        }

        private TreeNode build(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {
            if (inStart > inEnd || postStart > postEnd) {
                return null;
            }

            TreeNode node = new TreeNode(postorder[postEnd]);
            int inRootIndex = 0;
            for (int i = inStart; i <= inEnd; i++) {
                if (inorder[i] == node.val) {
                    inRootIndex = i;
                }
            }

            int leftSize = inRootIndex - inStart;
            //后序遍历的左树应该是 start 到size那里 ，右树应该是size + 1到 end - 1 那里
            node.left = build(inorder, inStart, inRootIndex - 1, postorder, postStart, postStart + leftSize - 1);
            node.right = build(inorder, inRootIndex + 1, inEnd, postorder, postStart + leftSize, postEnd - 1);
            return node;
        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}